home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 15 / develop 15 code / QD GX Shell / QuickDraw GX Shell - scroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-02  |  9.6 KB  |  326 lines  |  [TEXT/KAHL]

  1. /**
  2.  --
  3.  --        App:        QuickDraw GX Shell
  4.  --
  5.  --        Version:    1.0     1/93:    added general QuickDraw GX support & scrolling     
  6.  --                    1.1        4/93:    added support for QuickDraw GX printing and testing to
  7.  --                                    see is QuickDraw GX is installed.
  8.  --
  9.  --        File:        QuickDraw GX - scroll.c
  10.  --
  11.  --
  12.  --        Comments:    This file contains all of the code required to maintain and adjust
  13.  --                    the scroll bars attached to the window. We also update the mapping of 
  14.  --                    our child viewPort as the user scrolls. This approach guarantees that 
  15.  --                    all of the shapes within our QuickDraw GX picture are drawn in their 
  16.  --                    correct locations after scrolling.
  17.  --
  18.  --                    You can search on "QuickDraw GX Scrolling" to find the additions which
  19.  --                    were added to support QuickDraw GX Scrolling.
  20.  --
  21.  --        Components:    QuickDraw GX Shell (main).c
  22.  --                    QuickDraw GX Shell (main).h
  23.  --                    QuickDraw GX Shell - print.c
  24.  --                    QuickDraw GX Shell - print.h
  25.  --                    QuickDraw GX Shell - scroll.c
  26.  --                    QuickDraw GX Shell - scroll.h
  27.  --                    QuickDraw GX Shell (main).π.rsrc
  28.  --
  29.  --
  30.  --        Notes:        1) Print this file in landscape for the best results
  31.  --                    2) If you are using THINK C v5.x, I have added markers to navigate the 
  32.  --                       code.
  33.  --                    3) This code was adapted and simplyified from the "DTS AE Skeleton" sample.
  34.  --
  35.  --
  36.  --        Author:        Pete "Luke" Alexander
  37.  --                    Developer Technical Support
  38.  --                    AppleLink: DEVSUPPORT
  39.  --
  40.  --        
  41.  --        ©1992 - 1993  Apple Computer, Inc. 
  42.  **/
  43.  
  44. #include <Windows.h>
  45.  
  46. #include "QuickDraw GX Shell (main).h"
  47. #include "QuickDraw GX Shell - scroll.h"
  48.  
  49. #include "graphics routines.h"
  50. #include "math routines.h"
  51.  
  52. extern     gxShape         gthePage;
  53. extern    gxViewPort        gcontentViewPort;
  54.  
  55. //
  56. // Internal Function Prototypes
  57. //
  58. void ResizeScrollBars(WindowPtr theWindow);
  59. void InvalidateScrollBars(WindowPtr theWindow);
  60. void DoControl(Point thePoint, ControlHandle theControl, short controlPart);
  61. pascal void DoControlButton(ControlHandle theControl, short controlPart);
  62. void DoScroll(WindowPtr theWindow, short hScroll, short vScroll);
  63. void AdjustScrollBar(ControlHandle theControl);
  64.  
  65.  
  66. /**----- ResizeScrollBars --------------------------------------------------------------------
  67.  --
  68.  --        This function is used when the window is resized. It resizes the scroll bars to match.
  69.  --
  70.  **/
  71. void ResizeScrollBars(WindowPtr theWindow)
  72. {    
  73.     MoveControl(((MyWindowPeek)theWindow)->vScrollBar,
  74.                 theWindow->portRect.right-(kScrollBarWidth-1),
  75.                 theWindow->portRect.top-1);
  76.     SizeControl(((MyWindowPeek)theWindow)->vScrollBar, kScrollBarWidth,
  77.                 theWindow->portRect.bottom-theWindow->portRect.top-
  78.                 (kScrollBarWidth-3));
  79.     MoveControl(((MyWindowPeek)theWindow)->hScrollBar,
  80.                 theWindow->portRect.left-1,
  81.                 theWindow->portRect.bottom-(kScrollBarWidth-1));
  82.     SizeControl(((MyWindowPeek)theWindow)->hScrollBar,
  83.                 theWindow->portRect.right-theWindow->portRect.left-
  84.                 (kScrollBarWidth-3), kScrollBarWidth);
  85.     
  86.     AdjustScrollBar(((MyWindowPeek)theWindow)->hScrollBar);    
  87.     AdjustScrollBar(((MyWindowPeek)theWindow)->vScrollBar);
  88. }
  89.  
  90.  
  91.  
  92. /**----- InvalidateScrollBars ----------------------------------------------------------------
  93.  --
  94.  --        This function is used to invalidate the area under the scroll bars for redrawing.  
  95.  --        The invalid area will be included in the next update event.
  96.  --
  97.  **/
  98. void InvalidateScrollBars(WindowPtr theWindow)
  99. {
  100.     Rect    tempRect;
  101.     
  102.     SetPort(theWindow);
  103.     
  104.     tempRect = theWindow->portRect;
  105.     tempRect.left = tempRect.right-(kScrollBarWidth-1);
  106.     InvalRect(&tempRect);
  107.     EraseRect(&tempRect);
  108.     
  109.     tempRect = theWindow->portRect;
  110.     tempRect.top = tempRect.bottom-(kScrollBarWidth-1);
  111.     InvalRect(&tempRect);
  112.     EraseRect(&tempRect);
  113. }
  114.  
  115.  
  116.  
  117. /**----- DoControl ---------------------------------------------------------------------------
  118.  --
  119.  --        This function is used when the mouse is clicked on one of the scroll bars in a document. 
  120.  --
  121.  **/
  122. void DoControl(Point thePoint, ControlHandle theControl, short controlPart)
  123. {
  124.     short        oldValue;
  125.     short        amountToScroll;
  126.     WindowPtr    theWindow;
  127.     
  128.     switch (controlPart)
  129.     {
  130.     case inUpButton:
  131.     case inDownButton:
  132.     case inPageUp:
  133.     case inPageDown:
  134.         TrackControl(theControl, thePoint, (ProcPtr)DoControlButton);
  135.         break;
  136.     case inThumb:
  137.         oldValue = GetCtlValue(theControl);
  138.         if (TrackControl(theControl, thePoint, (ProcPtr)nil));
  139.         {
  140.             amountToScroll = - (GetCtlValue(theControl) - oldValue);
  141.             theWindow = (**theControl).contrlOwner;
  142.             if (((MyWindowPeek)theWindow)->hScrollBar == theControl)    /* horizontal? */
  143.                 DoScroll(theWindow, amountToScroll, 0);
  144.             else
  145.                 DoScroll(theWindow, 0, amountToScroll);
  146.             AdjustScrollBar(theControl);
  147.         }
  148.         break;
  149.     }
  150. }
  151.  
  152.  
  153.  
  154. /**----- DoControlButton ---------------------------------------------------------------------
  155.  --
  156.  --        This is the actionProc for the first call to TrackControl in DoControl.  This routine
  157.  --         is called by the operating system while the mouse button is being held on the UpButton, 
  158.  --        DownButton, PageUp, and PageDown areas.  It updates the window and scroll bars.
  159.  --
  160.  **/
  161. pascal void DoControlButton(ControlHandle theControl, short controlPart)
  162. {
  163.     WindowPtr    theWindow;
  164.     long        percent;
  165.     long        direction;
  166.     short        amountToScroll;
  167.     short        theMax, theValue;
  168.  
  169.     switch (controlPart)
  170.     {
  171.     case inUpButton:
  172.         percent = 15;
  173.         direction = 1;
  174.         break;
  175.     case inDownButton:
  176.         percent = 15;
  177.         direction = -1;
  178.         break;
  179.     case inPageUp:
  180.         percent = 90;
  181.         direction = 1;
  182.         break;
  183.     case inPageDown:
  184.         percent = 90;
  185.         direction = -1;
  186.         break;
  187.     default:
  188.         return;        /* IMPORTANT:  controlPart will often be zero - take no action! */
  189.     }    
  190.  
  191.     theWindow = (**theControl).contrlOwner;
  192.     
  193.     if (theControl == ((MyWindowPeek)theWindow)->hScrollBar)    /* Horizontal */
  194.         amountToScroll = (short)((long)(theWindow->portRect.right -
  195.                                         theWindow->portRect.left -
  196.                                         (kScrollBarWidth-1)) *
  197.                                         percent/100 * direction);
  198.     else                                                        /* Vertical */
  199.         amountToScroll = (short)((long)(theWindow->portRect.bottom -
  200.                                         theWindow->portRect.top -
  201.                                         (kScrollBarWidth-1)) *
  202.                                         percent/100 * direction);
  203.  
  204.     theValue = GetCtlValue(theControl);
  205.     theMax = GetCtlMax(theControl);
  206.  
  207.     /* Don't allow scrolling past limits */
  208.     if (amountToScroll < 0)        /* scrolling right or down */
  209.     {
  210.         if ((theValue + -amountToScroll) > theMax)
  211.             amountToScroll = - (theMax - theValue);
  212.     }
  213.     else    /* scrolling left or up */
  214.     {
  215.         if ((theValue + -amountToScroll) < 0)
  216.             amountToScroll = theValue;
  217.     }
  218.  
  219.     /* Scroll the contents of the window */
  220.     if (theControl == ((MyWindowPeek)theWindow)->hScrollBar)    /* Horizontal */
  221.         DoScroll(theWindow, amountToScroll, 0);
  222.     else                                                        /* Vertical */
  223.         DoScroll(theWindow, 0, amountToScroll);
  224.  
  225.     AdjustScrollBar(theControl);
  226. }
  227.  
  228.  
  229.  
  230. /**----- DoScroll ----------------------------------------------------------------------------
  231.  --
  232.  --        This procedure scrolls the contents of a document window an amount specified in
  233.  --        hScroll and vScroll, and fills the empty space created. We also adjust the mapping 
  234.  --        of our child viewPort - "gcontentViewPort". This ensures that all of our shapes
  235.  --        are drawn in the correct location after the scrolling.
  236.  --
  237.  **/
  238.  void DoScroll(WindowPtr theWindow, short hScroll, short vScroll)
  239. {
  240.     Rect            scrollRect;
  241.     Point            scrollPt;
  242.     RgnHandle        myRgn;
  243.     gxMapping        viewPortMapping;
  244.     
  245.     if ((hScroll == 0) && (vScroll == 0)) return;
  246.  
  247.     //
  248.     //    The user has scrolled the contents of the window, therefore we need
  249.     //    to update the mapping of the "gcontentViewPort" to reflect this change.
  250.     //    If we did not adjust the mapping or transform of all of our shape(s) on
  251.     //    the page, they would be redrawn in their original unscrolled location
  252.     //    because the geometry of each shape has not been changed.        
  253.     //   
  254.     //    We get the mapping of "gcontentViewPort", and adjust the mapping for the
  255.     //    scroll amount. We will then reset the mapping. The "ff" macro converts
  256.     //    an integer to their fixed point equivalents.                (QuickDraw GX Scrolling)
  257.     //                                                                 
  258.     GXGetViewPortMapping(gcontentViewPort, &viewPortMapping);
  259.  
  260.     GXMoveMapping(&viewPortMapping, ff(hScroll), ff(vScroll));
  261.  
  262.     GXSetViewPortMapping(gcontentViewPort, &viewPortMapping);
  263.  
  264.  
  265.     /* Scroll contents of window except for scroll bars */
  266.     scrollRect = theWindow->portRect;
  267.     scrollRect.right -= (kScrollBarWidth-1);
  268.     scrollRect.bottom -= (kScrollBarWidth-1);
  269.  
  270.     SetPort(theWindow);
  271.     myRgn = NewRgn();
  272.     
  273.     ScrollRect(&scrollRect, hScroll, vScroll, myRgn);
  274.     SetPt(&scrollPt, hScroll, vScroll);
  275.  
  276.     AddPt(scrollPt, &((MyWindowPeek)theWindow)->origin);
  277.  
  278.     DrawWindow(theWindow);
  279.  
  280.     DisposeRgn(myRgn);
  281. }
  282.  
  283.  
  284.  
  285. /**----- AdjustScrollBar ---------------------------------------------------------------------
  286.  --
  287.  --        This function looks at the current state of the window, and adjusts the maximum, 
  288.  --        minimum, and current values for both scroll bars.
  289.  --
  290.  **/
  291. void AdjustScrollBar(ControlHandle theControl)
  292. {
  293.     WindowPtr    theWindow;
  294.     Rect        picFrame;
  295.     short        delta1, delta2;
  296.     short        theMax;
  297.  
  298.     theWindow = (**theControl).contrlOwner;
  299.     picFrame = ((MyWindowPeek)theWindow)->documentBoundsRect;
  300.     OffsetRect(&picFrame, -picFrame.left, -picFrame.top);        /* Adjust upper left to 0,0 */
  301.  
  302.     if (theControl == ((MyWindowPeek)theWindow)->hScrollBar)    /* Horizontal scroll bar */
  303.     {
  304.         delta1 = - theWindow->portRect.left - ((MyWindowPeek)theWindow)->origin.h;
  305.         delta2 = - delta1 + picFrame.right - (theWindow->portRect.right -
  306.                  theWindow->portRect.left - (kScrollBarWidth-1));
  307.     }
  308.     else    /* Vertical scroll bar */
  309.     {
  310.         delta1 = - theWindow->portRect.top - ((MyWindowPeek)theWindow)->origin.v;
  311.         delta2 = - delta1 + picFrame.bottom - (theWindow->portRect.bottom -
  312.                  theWindow->portRect.top - (kScrollBarWidth-1));
  313.     }
  314.     
  315.     theMax = 0;
  316.     if (delta1 > 0) theMax += delta1;
  317.     if (delta2 > 0) theMax += delta2;
  318.     
  319.     if (theMax > 0)
  320.     {
  321.         SetCtlMax(theControl, theMax);
  322.         SetCtlValue(theControl, delta1);
  323.     }
  324.     else
  325.         SetCtlMax(theControl, 0);
  326. }